﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;

namespace YJKFamilyLibManager.ForProject
{
	[Regeneration(RegenerationOption.Manual)]
	[Transaction(TransactionMode.Manual)]
	public class CmdProjectToProject : YJKCommandManual
	{
		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			try
			{
				OpenFileDialog openFileDialog = new OpenFileDialog();
				openFileDialog.Filter = "Revit模型|*.rvt";
				if (openFileDialog.ShowDialog() == DialogResult.OK)
				{
					if (openFileDialog.FileName == cmdData.Application.ActiveUIDocument.Document.PathName)
					{
						MessageBox.Show("请选择其他文档导入。");
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					Document document = null;
					try
					{
						document = cmdData.Application.Application.OpenDocumentFile(openFileDialog.FileName);
					}
					catch (Autodesk.Revit.Exceptions.OperationCanceledException)
					{
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					Dictionary<string, List<Family>> dictionary = new Dictionary<string, List<Family>>();
					foreach (Family family in new FilteredElementCollector(document).OfClass(typeof(Family)).WhereElementIsNotElementType().Cast<Family>().ToList<Family>())
					{
						Category familyCategory = RevitVersionFuncs.GetFamilyCategory(family);
						if (dictionary.ContainsKey(familyCategory.Name))
						{
							dictionary[familyCategory.Name].Add(family);
						}
						else
						{
							List<Family> list = new List<Family>();
							list.Add(family);
							dictionary.Add(familyCategory.Name, list);
						}
					}
					DlgFamilyProToPro dlgFamilyProToPro = new DlgFamilyProToPro(dictionary);
					if (dlgFamilyProToPro.ShowDialog() == DialogResult.OK)
					{
						string tempPath = Path.GetTempPath();
						List<Family> list2 = new List<Family>();
						foreach (object obj in dlgFamilyProToPro.tvFamily.Nodes)
						{
							TreeNode tn = (TreeNode)obj;
							this.getAllFamilyFromTree(tn, list2);
						}
						SaveAsOptions saveAsOptions = new SaveAsOptions();
						saveAsOptions.OverwriteExistingFile = true;
						foreach (Family family2 in list2)
						{
							if (family2.IsEditable)
							{
								try
								{
									Document document2 = document.EditFamily(family2);
									RevitVersionFuncs.SaveAs(document2, tempPath + family2.Name, saveAsOptions);
									document2.Close(false);
									FileInfo fileInfo = new FileInfo(tempPath + family2.Name);
									Transaction transaction = new Transaction(this.m_doc, "LoadFamily");
									try
									{
										transaction.Start();
										this.m_doc.LoadFamily(fileInfo.FullName);
										transaction.Commit();
									}
									catch
									{
										transaction.RollBack();
									}
									finally
									{
										fileInfo.Delete();
									}
								}
								catch (Exception)
								{
									throw;
								}
							}
						}
					}
					document.Close(false);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			return base.YJKExcute(cmdData, ref message, elements);
		}

		private void getAllFamilyFromTree(TreeNode tn, List<Family> familyList)
		{
			foreach (object obj in tn.Nodes)
			{
				TreeNode treeNode = (TreeNode)obj;
				if (treeNode.Checked && treeNode.Tag is Family)
				{
					familyList.Add(treeNode.Tag as Family);
				}
			}
		}
	}
}
